//
//  UIButton+Extensions.swift
//  Extensions
//
//  Created by gupengling on 2021/6/5.
//  Copyright © 2021 gupengling. All rights reserved.
//

import UIKit

public typealias ActionBlock = (_ sender: AnyObject?) -> Void
private var AssociatedActionHandle: UInt8 = 0

public extension WDExtension where Base: UIButton {
    @discardableResult
    ///addTarget(_ target: Any?, action: Selector, for controlEvents: UIControl.Event)
    func target(add target: Any?, action: Selector, event: UIControl.Event = .touchUpInside) -> WDExtension {
        base.addTarget(target, action: action, for: event)
        return self
    }
    
    func target(remove target: Any?, action: Selector, event: UIControl.Event = .touchUpInside) -> WDExtension {
        base.removeTarget(target, action: action, for: event)
        return self
    }
    
    @discardableResult
    func select(_ b: Bool) -> WDExtension {
        base.isSelected = b
        return self
    }
    
    @discardableResult
    func line(breakMode mode: NSLineBreakMode) -> WDExtension {
        base.titleLabel?.lineBreakMode = mode
        return self
    }
    
    @discardableResult
    func image(_ image: UIImage?, for state:UIControl.State = .normal) -> WDExtension {
        base.setImage(image, for: state)
        return self
    }
    @discardableResult
    func background(_ image: UIImage?, for state:UIControl.State = .normal) -> WDExtension {
        base.setBackgroundImage(image, for: state)
        return self
    }
    
    @discardableResult
    func attributed(_ title: NSAttributedString, for state:UIControl.State = .normal) -> WDExtension {
        base.setAttributedTitle(title, for: state)
        return self
    }
    
    @discardableResult
    func title(_ edgeInsets: UIEdgeInsets) -> WDExtension {
        base.titleEdgeInsets = edgeInsets
        return self
    }
    
    @discardableResult
    func title(edgeInsets top: CGFloat = 0, left:CGFloat = 0, bottom:CGFloat = 0, right:CGFloat = 0) -> WDExtension {
        base.titleEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
        return self
    }
    
    @discardableResult
    func image(_ edgeInsets: UIEdgeInsets) -> WDExtension {
        base.imageEdgeInsets = edgeInsets
        return self
    }
    
    @discardableResult
    func image(edgeInsets top: CGFloat = 0, left:CGFloat = 0, bottom:CGFloat = 0, right:CGFloat = 0) -> WDExtension {
        base.imageEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
        return self
    }
    
    @discardableResult
    func contentAlignment(horizontal: UIControl.ContentHorizontalAlignment) -> WDExtension {
        base.contentHorizontalAlignment = horizontal
        return self
    }
    @discardableResult
    func contentAlignment(vertical: UIControl.ContentVerticalAlignment) -> WDExtension {
        base.contentVerticalAlignment = vertical
        return self
    }
    @discardableResult
    func imageViewContent(_ mode: UIView.ContentMode) -> WDExtension {
        base.imageView?.contentMode = mode
        return self
    }
    @discardableResult
    func reverses(_ titleShadowWhenHighlighted: Bool) -> WDExtension {
        base.reversesTitleShadowWhenHighlighted = titleShadowWhenHighlighted
        return self
    }
    
    @discardableResult
    func adjusts(imageWhenHighlighted a: Bool) -> WDExtension {
        base.adjustsImageWhenHighlighted = a
        return self
    }
    
    @discardableResult
    func adjusts(imageWhenDisabled a: Bool) -> WDExtension {
        base.adjustsImageWhenDisabled = a
        return self
    }
    @discardableResult
    func shows(_ touchWhenHighlighted: Bool) -> WDExtension {
        base.showsTouchWhenHighlighted = touchWhenHighlighted
        return self
    }
    
    @discardableResult
    func loading(bgViewColor: UIColor = .clear,
                 bgViewFrame:CGRect = .zero,
                 style:UIActivityIndicatorView.Style = .gray,
                 activityColor:UIColor = .clear) -> WDExtension {
        base.isEnabled = false
        let activity = UIActivityIndicatorView(style: style)
        activity.startAnimating()
        let view = UIView()
        view.tag = -8668
        if bgViewFrame == .zero {
            base.superview?.layoutIfNeeded()
            view.frame = base.bounds
        }else{
            view.frame = bgViewFrame
        }
        if bgViewColor == .clear {
            view.backgroundColor = bgViewColor
        }else{
            view.backgroundColor = base.backgroundColor
        }
        if activityColor != .clear {
            activity.color = activityColor
        }
        activity.frame = view.bounds
        
        base.addSubview(view)
        view.addSubview(activity)
        return self
    }
    
    @discardableResult
    func loading(_ custom: (() -> Void)) -> WDExtension {
        base.isEnabled = false
        custom()
        return self
    }
    
    @discardableResult
    func loadingHidden(_ tag: Int = -8668) -> WDExtension {
        base.viewWithTag(tag)?.removeFromSuperview()
        base.isEnabled = true
        return self
    }
}

public extension UIButton {
    /// 遍历构造器(创建按钮可以添加点击事件)
    ///
    /// - Parameters:
    ///   - title: 按钮文字
    ///   - titleColor: 文字颜色
    ///   - fontSize: 文字大小
    ///   - image: 图片名字
    ///   - backImage: 背景图片名字
    ///   - target: target
    ///   - action: action
    ///   - event: UIControlEvents
    convenience init(title: String?,
                     titleColor: UIColor = UIColor.darkGray,
                     fontSize: CGFloat = 14,
                     image: String? = nil,
                     backImage: String? = nil,
                     target: AnyObject? = nil,
                     action: Selector? = nil,
                     event: UIControl.Event = .touchUpInside){
        self.init()
        
        self.setTitle(title, for: .normal)
        self.setTitleColor(titleColor, for: .normal)
        self.titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
        //传了图片才设置
        if let image = image {
            self.setImage(UIImage(named: image), for: .normal)
            self.setImage(UIImage(named: "\(image)_selected"), for: .highlighted)
        }
        //传了图片才设置背景图片
        if let backImage = backImage {
            self.setBackgroundImage(UIImage(named: backImage), for: .normal)
            self.setBackgroundImage(UIImage(named: "\(backImage)_highlighted"), for: .highlighted)
        }
        //添加事件
        if let target = target, let action = action {
            self.addTarget(target, action: action, for: event)
        }
    }
    
    /// 便利构造器
    convenience init(normalTitle: String? ,
                     selTitle: String? = nil,
                     font: UIFont? = UIFont.systemFont(ofSize: 14),
                     normalColor: UIColor? = UIColor.lightGray,
                     selColor: UIColor? = nil,
                     normalImage: UIImage? = nil,
                     selImage: UIImage? = nil,
                     target: Any?  = nil,
                     action: Selector?  = nil,
                     event: UIControl.Event? = .touchUpInside ) {
        self.init()
        //设置文字
        self.setTitle(normalTitle, for: UIControl.State.normal)
        self.setTitle(selTitle ?? normalTitle, for: UIControl.State.selected)
        self.titleLabel?.font = font
        //设置图片
        self.setImage(normalImage, for: UIControl.State.normal)
        self.setImage(selImage ?? normalImage, for: UIControl.State.selected)
        //设置文字颜色
        self.setTitleColor(normalColor, for: UIControl.State.normal)
        self.setTitleColor(selColor ?? normalColor, for: UIControl.State.selected)
        //设置响应事件
        if let target = target , let action = action {
            self.addTarget(target, action: action, for: event!)
        }
    }
    
    /// 设置背景照片,自定义
    func addBackgroundImage(normal:UIImage? = nil , selected:UIImage? = nil)  {
        if let normal = normal {
            self.setBackgroundImage(normal, for: UIControl.State.normal)
        }
        if let selected = selected {
            self.setBackgroundImage(selected, for: UIControl.State.selected)
        }
    }

    @objc var clickedBlock: ActionBlock? {
        get {
            let value = objc_getAssociatedObject(self, &AssociatedActionHandle) as? ActionBlock
            return value
        }
        set {
            objc_setAssociatedObject(self, &AssociatedActionHandle, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
            addTarget(self, action: #selector(buttonClicked(_:)), for: .touchUpInside)
        }
    }

    @objc private func buttonClicked(_ sender: UIButton) {
        if let clickedBlock = clickedBlock {
            clickedBlock(sender)
        }
    }
}

public enum ImageLocation {
  case left, right, top, bottom
}

public extension UIButton {
    /// 设置image位置（必须要先设置frame）
    /// - Parameters:
    ///   - location: 位置
    ///   - space: 标题与图片的间距
    func setImage(location: ImageLocation, space: CGFloat) {
        guard let label = titleLabel, let imageV = imageView else {
            return
        }
        let imageWidth = imageV.bounds.size.width
        let imageHeight = imageV.bounds.size.height
        let titleWidth = label.bounds.size.width
        let titleHeight = label.bounds.size.height
        let width = frame.size.width
        switch location {
        case .left:
            titleEdgeInsets = UIEdgeInsets.init(top: 0, left: space/2, bottom: 0, right: -space/2)
            imageEdgeInsets = UIEdgeInsets.init(top: 0, left: -space/2, bottom: 0, right: space/2)
        case .right:
            imageEdgeInsets = UIEdgeInsets.init(top: 0, left: (titleWidth + space/2), bottom: 0, right: -(titleWidth + space/2))
            titleEdgeInsets = UIEdgeInsets.init(top: 0, left:  -(imageWidth + space/2), bottom: 0, right: (imageWidth + space/2))
        case .top:
            imageEdgeInsets = UIEdgeInsets.init(top: -titleHeight - space/2, left:(width - imageWidth)/2, bottom: 0, right: (width - imageWidth)/2 - titleWidth)
            titleEdgeInsets = UIEdgeInsets.init(top: 0, left: -imageWidth, bottom: -imageHeight - space/2, right:  0)
        case .bottom:
            imageEdgeInsets = UIEdgeInsets.init(top: 0, left: (width - imageWidth)/2, bottom: -titleHeight - space/2, right: (width - imageWidth)/2 - titleWidth)
            titleEdgeInsets = UIEdgeInsets.init(top: -imageHeight - space/2, left: -imageWidth, bottom: 0, right: 0)
        }
    }
}
